package cn.ac.iie.di.tools;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import cn.ac.iie.di.global.GlobalParas;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import jdk.nashorn.internal.runtime.options.LoggingOption;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.log4j.Logger;

/**
 *
 * @author root
 */
public class UnzipTools {

    private static Logger logger = Logger.getLogger(UnzipTools.class);

    /**
     * Description: 本地解压Gzip文件
     *
     * @param fileDir 压缩包路径
     * @param inFileName Gzip文件名
     * @param decompressionDir 解压路径
     * @return
     */
    public boolean uncompressFileGZIP(String fileDir, String inFileName, String decompressionDir) {
        boolean flag = false;
        long startTime = System.currentTimeMillis();
        String outFileName = null;
        try {

            if (!getExtension(inFileName).equalsIgnoreCase("gz")) {
                logger.info("File name must have extension of \".gz\"");

                return flag;
            }

            logger.info("Opening the compressed file. 压缩包内容： " + fileDir + inFileName);
            GZIPInputStream in = null;
            try {
                in = new GZIPInputStream(new FileInputStream(fileDir + inFileName));
            } catch (FileNotFoundException e) {
                logger.info("File not found. " + fileDir + inFileName);

            }

            logger.info("Open the output file.");
            outFileName = getFileName(decompressionDir + inFileName);
            FileOutputStream out = null;
            try {
                out = new FileOutputStream(outFileName);
            } catch (FileNotFoundException e) {
                logger.info("Could not write to file. " + outFileName);

            }

            logger.info("Transfering bytes from compressed file to the output file. 解压文件至： " + decompressionDir + inFileName);
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            logger.info(fileDir + inFileName + "解压成功");

            logger.info("Closing the file and stream");
            in.close();
            out.close();

            flag = true;
        } catch (Exception e) {

        } finally {
            try {
                //创建.ok文件
                FileTools.creatTxtFile(outFileName + ".ok");
            } catch (IOException ex) {
                logger.info("create the .ok file " + outFileName + " error!");
            }
            logger.info("create the file " + outFileName + ".ok success!");
        }
        long endTime = System.currentTimeMillis();
        logger.info("解压gz压缩包开始时间： " + startTime + " ，结束时间：" + endTime + " ，消耗时间： " + (endTime - startTime) + " ms");
        return flag;
    }

    public static void main(String[] args) {
        Boolean b = uncompressFileZIP("D:\\123\\111", "1030036_querygroupfile_3_WXB_1334403000000000040_final.zip", "D:\\123\\222");
    }

    /**
     * Description: 本地解压Zip文件
     *
     * @param fileDir 解压路径
     * @param inFileName Zip文件名
     * @return
     */
    public static boolean uncompressFileZIP(String fileDir, String inFileName, String decompressionDir) {
        logger.info("this zip name  is : " + inFileName);
        boolean flag = false;
        long startTime = System.currentTimeMillis();
        try {
//fileDir + File.separator +
            ZipInputStream zin = new ZipInputStream(new FileInputStream(inFileName));//输入源zip路径 
            BufferedInputStream bin = new BufferedInputStream(zin);
            ZipEntry entry;
            String str = null;
            String okstr = null;
            String json = null;
            int fileNum = 0;
            String zipDir = inFileName.substring(inFileName.lastIndexOf(File.separator) + 1, inFileName.length()).split(".zip")[0];
            if (!new File(decompressionDir + File.separator + zipDir).exists()) {
                logger.info("creat ok Dir " + decompressionDir + File.separator + zipDir);
                while (!FileTools.createDir(decompressionDir + File.separator + zipDir)) {
                    logger.info("Dir " + decompressionDir + File.separator + zipDir + " creat fail!");
                }
            }
            try {
                // 实例化对象，指明要进行解压的文件
                entry = zin.getNextEntry();
                while (entry != null) {
                    if (entry.isDirectory()) {
                        logger.info("压缩包内容： " + fileDir + entry.getName());
                    } else {
                        if (entry.getName().endsWith(".json")) {
                            json = entry.getName();
                            okstr = entry.getName().split(".json")[0] + ".ok";
                        }
//                        String[] names = entry.getName().split(File.separator);
                        str = entry.getName();
                        byte[] buffer = new byte[1024];
                        logger.info("解压文件至： " + decompressionDir + File.separator + str);
                        FileOutputStream fos = new FileOutputStream(decompressionDir + File.separator + zipDir + File.separator + str);
                        BufferedOutputStream bos = new BufferedOutputStream(fos);
                        int b;
                        while ((b = bin.read(buffer)) > 0) {
                            bos.write(buffer, 0, b);
                        }

                        bos.close();
                        fos.close();
                        logger.info(fileDir + "/" + str + "解压成功");
                        fileNum++;

                    }
                    entry = zin.getNextEntry();
                }
                if (fileNum == 2) {
                    if (okstr != null) {
                        if (!new File(decompressionDir + File.separator + zipDir + File.separator + okstr).exists()) {
                            logger.info("creat ok file " + decompressionDir + File.separator + zipDir + File.separator + okstr);
                            while (!FileTools.creatTxtFile(decompressionDir + File.separator + zipDir + File.separator + okstr)) {
                                logger.info("file " + decompressionDir + File.separator + okstr + " creat fail!");
                            }
                        }
                        GlobalParas.jsonQueue.put(zipDir + "=" + okstr);
                        logger.debug("GlobalParas.jsonQueue.size(): " + GlobalParas.jsonQueue.size());
                    } else {
                        logger.info("okfile ");
                    }
                } else {
                    logger.info("the zip is bad :" + inFileName);
                    FileTools.deleteDir(new File(decompressionDir + File.separator + zipDir));
                }
            } catch (IOException e) {
                logger.error("解压文件" + fileDir + inFileName + "失败： " + e, e);

            } finally {
                try {
                    if (bin != null) {
                        bin.close();
                    }
                    if (bin != null) {
                        zin.close();
                    }

                } catch (IOException ex) {
                    logger.info("解压文件关闭流失败： " + ex);
                }

                logger.info("create the file " + decompressionDir + okstr + ".ok success!");
            }
        } catch (Exception e) {
            logger.info("文件" + fileDir + inFileName + "不存在： " + e);

        }
        flag = true;

        long endTime = System.currentTimeMillis();
        logger.info("解压zip压缩包开始时间： " + startTime + " ，结束时间：" + endTime + " ，消耗时间： " + (endTime - startTime) + " ms");
        return flag;
    }

    /**
     * Description: 本地解压TARGZ文件
     *
     * @param fileDir 解压路径
     * @param inFileName Zip文件名
     * @return
     */
    public static boolean uncompressFileTARGZ(String fileDir, String inFileName, String decompressionDir) {
        boolean flag = false;
        long startTime = System.currentTimeMillis();

        FileInputStream fis = null;
        ArchiveInputStream in = null;
        BufferedInputStream bis = null;
        String str = null;
        try {
            logger.info("解压文件： " + fileDir + inFileName);
            fis = new FileInputStream(fileDir + inFileName);
            GZIPInputStream is = new GZIPInputStream(new BufferedInputStream(fis));
            try {
                in = new ArchiveStreamFactory().createArchiveInputStream("tar", is);
            } catch (ArchiveException ex) {
                logger.info("失败： " + ex);
            }
            bis = new BufferedInputStream(in);
            TarArchiveEntry entry = (TarArchiveEntry) in.getNextEntry();

            while (entry != null) {
                String name = entry.getName();
                String[] names = name.split("/");

                for (int i = 0; i < names.length; i++) {
                    str = names[i];
                }

                if (!name.endsWith("/")) {
                    File f = new File(decompressionDir + str);
                    try {
                        f.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    logger.info("解压文件至" + decompressionDir + str);
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f));
                    int b;
                    while ((b = bis.read()) != -1) {
                        bos.write(b);
                    }

                    bos.flush();
                    bos.close();
                }
                entry = (TarArchiveEntry) in.getNextEntry();
            }
        } catch (Exception e) {
            logger.info("解压文件" + fileDir + inFileName + "失败： " + e);

        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
                if (in != null) {
                    in.close();
                }
                if (fis != null) {
                    fis.close();
                }

            } catch (IOException e) {
                logger.info("解压文件关闭流失败： " + e);
            }

            logger.info("create the file " + decompressionDir + str + ".ok success!");
        }
        flag = true;

        long endTime = System.currentTimeMillis();
        logger.info("解压tar.gz压缩包开始时间： " + startTime + " ，结束时间：" + endTime + " ，消耗时间： " + (endTime - startTime) + " ms");
        return flag;
    }

    //获取压缩包结尾
    public static String getExtension(String fileName) {
        String ext = "";
        int i = fileName.lastIndexOf('.');

        if (i > 0 && i < fileName.length() - 1) {
            ext = fileName.substring(i + 1);
        }
        return ext;
    }

    //获取压缩包去掉结尾的文件名
    public static String getFileName(String fileName) {
        String fname = "";
        int i = fileName.lastIndexOf('.');

        if (i > 0 && i < fileName.length() - 1) {
            fname = fileName.substring(0, i);
        }
        return fname;
    }

//    public static void main(String[] args) {
//        UnzipTools.uncompressFileGZIP("D:/123/", "pa_ivr_msg_2016_08_06_11_15_2016_08_06_11_20.gz", "D:/234/");
//    }
}
